import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:common/global/global_event.dart';
import 'package:common/model/simple_user_info/simple_user_info.dart';
import 'package:common/model/user_bloc_state/user_bloc_state.dart';
import 'package:common/preference/t_preference_key.dart';
import 'package:common/preference/t_preferences.dart';
import 'package:common/common.dart';
import 'package:common/util/t_util.dart';

class UserBloc extends Bloc<UserEvent, UserBlocState> {
  static const String blocName = "common.UserBloc";

  UserBloc(UserBlocState initialState) : super(initialState) {
    _currentState = initialState;
    Future.delayed(Duration(milliseconds: 100), () => add(UserInitEvent()));
  }

  static UserBlocState _currentState;
  static bool _isOffline = false;
  static bool _isManualLogin = false;

  static bool get isOffline => _isOffline ?? false;

  static String get token => _currentState.token;

  static String get imToken => _currentState.imToken;

  static bool get isManualLogin => _isManualLogin ?? false;

  @override
  Stream<UserBlocState> mapEventToState(UserEvent event) async* {
    if (event is UserIMUpdateEvent) {
      _currentState.imToken = event.token;
      _currentState.imUserId = event.userId;
      TPreferences().get.then((value) => value.setString(TPreferenceKey.user, _currentState.toJsonString()));
      yield _currentState.copy();
      return;
    }
    if (event is UserInitEvent) {
      SharedPreferences prefs = await TPreferences().get;
      if(UserBloc.isOffline){
        prefs.setString(TPreferenceKey.user, prefs.getString(TPreferenceKey.userBackup));
      }
      final userString = prefs.getString(TPreferenceKey.user);
      print("Bloc: Common markA: UserBloc.isOffline=${UserBloc.isOffline}");
      if (TUtil.isNotEmptyString(userString)) {
        UserBlocState parsedState = UserBlocState.fromJsonString(userString);
        if (parsedState.type == 0) {
          parsedState = null;
          print("Bloc: userInfo清除");
          prefs.remove(TPreferenceKey.user);
        }

        if (parsedState?.token != null) {
          add(_UserUpdateEvent(parsedState));
          Future.delayed(Duration(milliseconds: 100), () {
            GlobalBroadcast.send(GlobalLoginEvent());
            Future.delayed(Duration(milliseconds: 1500), () {
              print("TBloc: 开始检查token是否为空");
              if (parsedState.token != null) {
                print("TBloc: token不为空，开始请求个人信息");
                GlobalBroadcast.send(GlobalRequestUserInfoEvent(parsedState.token));
              }
            });
          });
        } else {
          prefs.remove(TPreferenceKey.user);
          add(_UserUpdateEvent(UserBlocState(status: UserStatus.Idle)));
        }
      } else {
        await Future.delayed(Duration(milliseconds: 1500), () {
          add(_UserUpdateEvent(UserBlocState(status: UserStatus.Idle)));
        });
      }
      return;
    }

    if (event is UserManualLoginEvent) {
      _isManualLogin = event.isManualLogin;
      return;
    }

    if (event is UserOfflineUpdateEvent) {
      print("Bloc: Common: UserOfflineUpdateEvent: isOffline=${event.isOffline}");
      _isOffline = event.isOffline;
      GlobalBroadcast.send(GlobalOfflineUpdateEvent(event.isOffline));
      if (event.isOffline) {
        add(UserInitEvent());
      }
      return;
    }

    if (event is UserTokenUpdateEvent) {
      _currentState.token = event.token;
      _currentState.type = event.type;
      _currentState.status = UserStatus.LoggingIn;
      yield _currentState.copy();
      return;
    }

    if (event is UserUserInfoUpdateEvent) {
      print(
          "Bloc: Login: UserUserInfoUpdateEvent: userInfo=${event.userInfo.toJson().toString()}, isOffline=$_isOffline");
      _currentState.userInfo = event.userInfo;
      _currentState.status = UserStatus.LoggedIn;
      SharedPreferences preferences = await TPreferences().get;
      preferences.setString(TPreferenceKey.user, _currentState.toJsonString());
      if (UserBloc.isManualLogin) {
        preferences.setString(TPreferenceKey.userBackup, _currentState.toJsonString());
      }
      yield _currentState.copy();
      Future.delayed(
        Duration(milliseconds: 100),
        () => GlobalBroadcast.send(GlobalLoginEvent()),
      );
      return;
    }

    if (event is UserLogoutEvent) {
      print("Dio: 收到退出登录的消息");
      _currentState = UserBlocState(status: UserStatus.LoggedOut);
      yield _currentState;
      _isManualLogin = false;
      _isOffline = false;
      TPreferences().get.then((value) => value.remove(TPreferenceKey.user));
      await Future.delayed(Duration(milliseconds: 100), () {
        GlobalBroadcast.send(GlobalLogoutEvent());
      });
      _currentState.status = UserStatus.Idle;
      yield _currentState.copy();
      return;
    }
    if (event is UserTypeUpdateEvent) {
      _currentState.type = event.type;
      yield _currentState.copy();
      return;
    }

    if (event is _UserUpdateEvent) {
      _currentState = event.state;
      yield event.state;
    }
  }
}

class UserOfflineUpdateEvent extends UserEvent {
  bool isOffline;

  UserOfflineUpdateEvent(this.isOffline);
}

class UserIMUpdateEvent extends UserEvent {
  String token;
  String userId;

  UserIMUpdateEvent(this.token, this.userId);
}

class UserTypeUpdateEvent extends UserEvent {
  final int type;

  UserTypeUpdateEvent(this.type);
}

class UserManualLoginEvent extends UserEvent {
  final bool isManualLogin;

  UserManualLoginEvent(this.isManualLogin);
}

class UserLogoutEvent extends UserEvent {}

class UserTokenUpdateEvent extends UserEvent {
  final String token;
  final int type;

  UserTokenUpdateEvent(this.token, this.type);
}

class UserUserInfoUpdateEvent extends UserEvent {
  final SimpleUserInfo userInfo;

  UserUserInfoUpdateEvent(this.userInfo);
}

class _UserUpdateEvent extends UserEvent {
  final UserBlocState state;

  _UserUpdateEvent(this.state);
}

class UserInitEvent extends UserEvent {}

abstract class UserEvent {}
